//
// Created by pzw on 24-3-15.
//

#ifndef QTTEST_FINDSORT_H
#define QTTEST_FINDSORT_H

#include <vector>
#include <list>
#include <algorithm>
#include <iostream>
#include <random>
#include <cstdlib>
#include <functional>

class Book;

class FindSort {
public:
    FindSort() = default;
    ~FindSort() = default;
public:
    template<template<typename, typename ...> class List, typename Tp>
    static void std_sort_list(List<Tp> &list);
    template<template<typename ...> class List, typename Tp>
    static void std_sort_list2(List<Tp> &list);
    static void std_partial_sort_copy(const std::vector<Book> &sales);
    template<typename Tp, typename Compare = std::less<Tp>>
    static void std_binary_search(const std::vector<Tp> &vs, const Tp &target, Compare comp = Compare());
    template<typename Tp>
    static void std_binary_search2(const std::vector<Tp> &vs, const Tp &target);
    template<typename Tp, typename Tp2>
    static void std_merge_vector_list(std::vector<Tp> &vs, std::list<Tp2> lst);
    template<typename Tp, typename Tp2>
    static void std_merge_vector_list2(std::vector<Tp> &vs, std::list<Tp2> lst);
    static void std_set_union_diff(std::string s1, std::string s2);
    static void std_heap_func(std::string s);
    template<typename Tp, typename Tp2>
    static bool std_lexicographical_compare(Tp tp, Tp2 tp2);
};

class Book {
private:
    long copiesSold{};
    double copiesSoldf{};
public:
    explicit Book() = default;

    explicit Book(long sold) : copiesSold(sold), copiesSoldf(-1.0f) {};

    explicit Book(double sold) : copiesSold(-1), copiesSoldf(sold) {};

    ~Book() = default;
public:
    long copies_sold() const {
        return copiesSold;
    }

    double copies_soldf() const {
        return copiesSoldf;
    }

    /**
     * 使用一个toString，类似java
     *
     * @return std::string
     */
    std::string toString() const {
        std::string str;
        str.append("\"Book\" : {")
                .append("\"copiesSold\" : ")
                .append(std::to_string(copiesSold))
                .append(", ")
                .append("\"copiesSoldf\" : ")
                .append(std::to_string(copiesSoldf))
                .append("}");
        return str;
    }

    /**
     * 重载小于<操作符，使得我们可以按照int一样进行大小比较
     *
     * @param lhs 较小值?
     * @return bool
     */
    bool operator<(const Book &lhs) const {
        return lhs.copiesSold < this->copiesSold;
    }

    /**
     * 让我们的Book类型也可以按照iostream的<<格式进行输出；
     *
     * @param os 传入标准输出
     * @return 返回拼接后的标准输出
     */
    std::ostream &operator<<(std::ostream &os) const {
        os << this->toString();
        return os;
    }
};

int FindSort_main();

#endif //QTTEST_FINDSORT_H
